<?
/**! SOAP (Simple object access protocol) server and client procedures.

    This collection of functions (libary) is licensed under GPL2.
    See LICENSE or www.gnu.org for more details.
 */

/** delimiters */
define(SOAP_ANS_DELIM, "<BR>\n");   /** delimits one key/item from another in
                                     *  return values */
define(SOAP_END_TAG, "<===<BR>\n"); /** end of the answer mark that is
                                     *  transmited back to the client side */

/** reception times */
define(SOAP_WAIT, 5);               /** how long in secs to wait for an answer
                                     *  at the client side */
define(SOAP_RETRIES, 5);            /** how many times to try waiting for an
                                     * answer at the client side */


/** Client function to use SOAP server.
 *  >$AddrStr:str URL to call and pass parameters to.
 *  >$Values:soSet Set of values to pass to the server.
 *  <:$Compress:bool When set(1), compresses passed values before sending.
 *  <:soSet Values returned.
 */
function soSoapCall($Url, $Values, $Compress = 0) {
    $keys = $Values->getKeys();
    $vars = "";
    foreach ($keys as $key) {
        $vars = soJoinStr($vars, "&",
                          urlencode($key)."=".
                          urlencode($Values->getItem($key)), 1);
    }; // foreach

    $result = new soSet();
    $fp = fopen($Url."?".$vars, "r");
    if ($fp) {

        $answer = "";
        fputs($fp, "GET / HTTP/1.0\n\n");
        $retries = SOAP_RETRIES;
        $waiting = 1;
        $start_time = time();
        $answer = "";

        while (($retries > 0) && ($waiting)) {
            while (!feof($fp)) {

                /* Due to some strange bug or behaviour in PHP 4.0.5,
                   $ans .= fgets($fp, 1512) does not work. */
                $answer .= fread($fp, 1512);

                if (substr($answer, strlen($answer) -strlen(SOAP_END_TAG)) ==
                    SOAP_END_TAG) $waiting = 0;

            }; // while feof
            if ($waiting && ($start_time +SOAP_WAIT > time())) {
                $start_time = time();
                $retries--;
            };
        }; // while $retries
        fclose($fp);

        $ans_array = soExplode(urldecode($answer), SOAP_ANS_DELIM);
        foreach ($ans_array as $item) {
            $split = soSplitStr($item, "=", 1);
            if ($split[0] != "") {
                $result->addItem(urldecode($split[0]), urldecode($split[1]));
            };
        }; // foreach
    } // if fp

    return $result;
}; // soSoapCall


/** Server side listener.
 *  Catches and returns the parameters sent from the client side.
 *  <:soSet Set of values.
 */
function soSoapCatch() {
    global $HTTP_GET_VARS;

    $result = new soSet();
    $result->joinArray($HTTP_GET_VARS);
    $keys = $result->getKeys();
    foreach ($keys as $key) {
        $result->setItem(urldecode($key), urldecode($result->getItem($key)));
    }; // foreach

    return $result;
}; // soSoapCatch


/** Server side sender.
 *  Sends the answer to the client side.
 *  <$Values:soSet Values to send back to the client side.
 */
function soSoapAnswer($Values) {
    $keys = $Values->getKeys();
    foreach ($keys as $key) {
        echo urlencode($key)."=".
             urlencode($Values->getItem($key)).
             SOAP_ANS_DELIM;
    }; // foreach
    echo SOAP_END_TAG;
}; // soSoapCatch


?>
